package com.deimos.sps;

import java.util.Date;
import java.util.List;
import org.vast.ows.OWSException;
import org.vast.ows.sps.StatusReport;
import org.vast.ows.sps.TaskingResponse;
import org.vast.ows.sps.StatusReport.TaskStatus;
import org.vast.xml.DOMHelperException;

import com.deimos.Notification;
import com.deimos.UtilsDeimos;
import com.deimos.dataBase.Event;
import com.deimos.dataBase.Task;
import com.deimos.dataBase.TaskController;
import com.spotimage.eosps.EOReportHelper;
import com.spotimage.eosps.ValidateRequest;
import com.spotimage.eosps.ValidateResponse;
import com.spotimage.eosps.EOConstants.AcqStatus;

public class Validate {
    ValidateRequest request = null;
    ValidateResponse response = null;
    Task task = null;
    String validatedS = "";

    public Validate(ValidateRequest request) {
	this.request = request;
    }

    public ValidateResponse buildResponse() throws OWSException, DOMHelperException {
	String id = request.getTaskID();

	TaskController taskController = new TaskController();

	response = new ValidateResponse();

	taskController.validateStatus(id);
	taskController.validateSegments(id);
	Event event = taskController.getLastEvent(id);
	if (event == null)
	    throw new OWSException(OWSException.invalid_param_code, "task", request.getTaskID(), request.getTaskID() + " task not found into the database");

	String newSegments = replaceSegments(event.getResponseParameters(), (setSegmentsStatus(UtilsDeimos.readParams(event.getResponseParameters()), event, request.getSegmentIDs())));

	if (newSegments != null) {
	    event.setDescription(newSegments.split("description")[1].split(">")[1].split("<")[0]);
	    event.setResponseParameters(newSegments);
	}

	if (validatedS.split(",").length >= 0) {
	    event.setEventId(null);
	    event.setResponseParameters(newSegments);
	    event.setUpdateDate(new Date());
	    event.setRequestStatus(null);
	    /*if (taskController.isSegmentsFailed(UtilsDeimos.readParams(event.getResponseParameters()))) {
		event.setTaskStatus(TaskStatus.Failed);
		System.out.println(event.getTask().getTaskId() + ": Task failed");
		Notification.notifyReport(event);
	    } else {*/
		event.setTaskStatus(TaskStatus.Completed);
		System.out.println(event.getTask().getTaskId() + ": Task Completed");
		Notification.notifyReport(event);
	    //}
	    taskController.insertEvent(event);
	}

	StatusReport rp = UtilsDeimos.generateReport(event);
	rp.setDescription(validatedS.split(",").length + " segments validated " + this.validatedS);
	rp.setTitle("Validate Request");

	response.setReport(rp);
	response.setVersion("2.0.0");
	response.setService("EOSPS");

	return response;
    }

    @SuppressWarnings("unchecked")
    private String setSegmentsStatus(TaskingResponse response, Event event, List<String> segments) throws OWSException {
	boolean cancelled = false, validated = false;
	StatusReport report = response.getReport();
	if (report.getExtensions() == null)
	    return null;
	EOReportHelper eohelper = new EOReportHelper(report);
	for (String segment : segments) {
	    boolean encontrado = false;
	    for (int i = 0; i < eohelper.getNumSegments(); i++) {
		eohelper.loadSegment(i);
		if (eohelper.getObjectStatus() == AcqStatus.ACQUIRED && eohelper.getID().compareTo(segment) == 0) {
		    eohelper.setObjectStatus(AcqStatus.VALIDATED);
		    validated = true;
		    encontrado = true;
		    if (validatedS.isEmpty())
			validatedS = "(" + segment;
		    else
			validatedS = validatedS + ", " + segment;
		} else if (eohelper.getID().compareTo(segment) == 0) {
		    encontrado = true;
		}
	    }
	    if (!encontrado)
		throw new OWSException(OWSException.invalid_param_code, "segmentID", segment, segment + " segmentID not found into the database");
	}
	if (validatedS.isEmpty())
	    throw new OWSException(OWSException.invalid_param_code, "segmentID", "No acquired segments to validate. ");
	if (!validatedS.isEmpty())
	    validatedS = validatedS.replaceFirst(" ,", "") + ") ";

	for (int i = 0; i < eohelper.getNumSegments(); i++) {
	    eohelper.loadSegment(i);
	    if (eohelper.getObjectStatus() != AcqStatus.VALIDATED && eohelper.getObjectStatus() != AcqStatus.CANCELLED && eohelper.getObjectStatus() != AcqStatus.REJECTED && eohelper.getObjectStatus() != AcqStatus.FAILED) {
		eohelper.setObjectStatus(AcqStatus.CANCELLED);
		cancelled = true;
	    }
	}
	eohelper.writeReportInfo();
	report.touch();
	if (cancelled)
	    Notification.getInstance().notifySegmentCancelled(report);
	if (validated)
	    Notification.getInstance().notifySegmentValidated(report);
	return UtilsDeimos.getParameters(response);

    }

    private String replaceSegments(String params, String newParams) {
	if (params == null || newParams == null)
	    return null;
	String newResponse = null;
	String paramsType = "", newParamsType = "";
	if (params.contains("FeasibilityStudy"))
	    paramsType = "FeasibilityStudy";
	else
	    paramsType = "ProgrammingStatus";

	if (newParams.contains("FeasibilityStudy"))
	    newParamsType = "FeasibilityStudy";
	else
	    newParamsType = "ProgrammingStatus";
	String[] splitparams = params.split(paramsType);
	String[] splitnewParams = newParams.split(newParamsType);
	if (splitparams.length == 3 && splitnewParams.length == 3 && splitnewParams[1].compareTo(splitparams[1]) != 0) {
	    newResponse = splitparams[0] + newParamsType + splitnewParams[1] + newParamsType + splitparams[2];
	}

	return newResponse;
    }
}
